The Art of UNIX Programming
https://gyazo.com/7bc5fc74cbd53afb8a42c01d5a337a45
序章
第1部 コンテキスト
第1章 思想:大切なのは思想だ
1.1 文化? なんのこと?
1.2 Unixの生命力
1.3 Unix文化の学習に対する反対論
1.4 Unixの短所
1.5 Unixの長所
1.5.1オープンソースソフトウェア
1.5.2 プラットフォームを越えた移植性とオープンな標準
1.5.3 インターネットとWeb
1.5.4 オープンソースコミュニティ
1.5.5 あらゆる面での柔軟性
1.5.6 ハックして楽しいUnix
1.5.7 他の場面にも応用できるUnixの教訓
1.6 Unix思想の基礎
1.6.1 モジュール化の原則:クリーンなインターフェイスで結合される単純な部品を作れ
1.6.2 明確性の原則:巧妙になるより明確であれ
1.6.3 組み立て部品の原則:他のプログラムと組み合わせられるように作れ
1.6.4 分離の原則:メカニズムからポリシーを切り離せ。エンジンからインターフェイスを切り離せ
1.6.5 単純性の原則:単純になるように設計せよ。複雑な部分を追加するのは、どうしても必要なときだけに制限せよ
1.6.6 倹約の原則:他のものでは代えられないことが明確に実証されない限り、大きなプログラムを書くな
1.6.7 透明性の原則:デバッグや調査が簡単になるように、わかりやすさを目指して設計せよ
1.6.8 安定性の原則:安定性は、透明性と単純性から生まれる
1.6.9 表現性の原則:知識をデータのなかに固め、プログラムロジックが楽で安定したものになるようにせよ
1.6.10 驚き最小の原則:インターフェイスは、驚きが最小になるように設計せよ
1.6.11 沈黙の原則:どうしてもいわなければならない想定外なことがないのなら、プログラムは何もいうな
1.6.12 修復の原則:エラーを起こさなければならないときには、できる限り早い段階でけたたましくエラーを起こせ
1.6.13 経済性の原則:プログラマの時間は高価だ。マシンの時間よりもプログラマの時間を節約せよ
1.6.14 生成の原則:手作業のハックを避けよ。可能なら、プログラムを書くためのプログラムを書け
1.6.15 最適化の原則:磨く前にプロトタイプを作れ。最適化する前にプロトタイプが動くようにせよ
1.6.16 多様性の原則:「唯一の正しい方法」とするすべての主張を信用するな
1.6.17 拡張性の原則:未来は予想外に早くやってくる。未来を見すえて設計せよ
1.7 Unix思想を一言でまとめると
1.8 Unix思想の応用
1.9 姿勢も大切
第2章 歴史:2つの文化の物語
2.1 Unixの起源と歴史:1969-1995
2.1.1 創世記:1969-1971
2.1.2 出エジプト記:1971-1980
2.1.3 TCP/IPとUnix戦争:1980-1990
2.1.4 帝国への反撃:1991-1995
2.2 ハッカーの起源と歴史:1961-1995
2.2.1 象牙の塔のなかでの遊び:1961-1980
2.2.2 インターネットによる融合とフリーソフトウェア運動:1981-1991
2.2.3 Linuxとプラグマティストの反応:1991-1998
2.3 オープンソース運動:1998年から現在まで
2.4 Unixの歴史が示す教訓
第3章 対比:Unix思想と他のOS
3.1 オペレーティングシステムのスタイルを構成する要素
3.1.1 オペレーティングシステムの基本思想
3.1.2 マルチタスク機能
3.1.3 プロセスの共同作業
3.1.4 内部区分
3.1.5 ファイル属性とレコード構造
3.1.6 バイナリファイルフォーマット
3.1.7 ユーザーインターフェイススタイル
3.1.8 対象とするユーザー
3.1.9 プログラマになるための障壁
3.2 オペレーティングシステムの比較
3.2.1 VMS
3.2.2 MacOS
3.2.3 OS/2
3.2.4 Windows NT
3.2.5 BeOS
3.2.6 MVS
3.2.7 VM/CMS
3.2.8 Linux
3.3 死んだものと残ったもの、その理由
第2部 設計
第4章 モジュール化:簡潔に、単純に
4.1 カプセル化と最適なモジュールサイズ
4.2 簡潔性と直交性
4.2.1 簡潔性
4.2.2 直交性
4.2.3 SPOT原則
4.2.4 簡潔性と強力な単純の中心にあるもの
4.2.5 独立性の価値
4.3 ソフトウェアにはたくさんの階層がある
4.3.1 トップダウン対ボトムアップ
4.3.2 グルーレイヤ
4.3.3 ケーススタディ:薄いグルーとしてのC
4.4 ライブラリ
4.4.1 ケーススタディ:GIMPプラグイン
4.5 Unixとオブジェクト指向言語
4.6 モジュール化を実現するコーディング
第5章 テキスト形式:優れたプロトコルが優れた実践を生む
5.1 テキストであることの重要性
5.1.1 ケーススタディ:Unixパスワードファイルフォーマット
5.1.2 ケーススタディ:.newsrcフォーマット
5.1.3 ケーススタディ:PNGグラフィックスファイルフォーマット
5.2 データファイルメタフォーマット
5.2.1 DSVスタイル
5.2.2 RFC 822フォーマット
5.2.3 クッキージャーフォーマット
5.2.4 レコードジャーフォーマット
5.2.5 XML
5.2.6 Windows INIフォーマット
5.2.7 Unixのテキストファイルフォーマットに見られる慣習
5.2.8 ファイル圧縮のメリットとデメリット
5.3 アプリケーションプロトコルの設計
5.3.1 ケーススタディ:SMTP(Simple Mail Transfer Protocol)
5.3.2 ケーススタディ:POP3(Post Office Protocol)
5.3.3 ケーススタディ:IMAP(Internet Message Access Protocol)
5.4 アプリケーションプロトコルメタフォーマット
5.4.1 古典的なインターネットアプリケーションのメタプロトコル
5.4.2 普遍的なアプリケーションプロトコルとしてのHTTP
5.4.3 BEEP(Blocks Extensible Exchange Protocol)
5.4.4 XML-RPC、SOAP、Jabber
第6章 透明性:光あれ
6.1 ケーススタディ
6.1.1 ケーススタディ:audacity
6.1.2 ケーススタディ:fetchmailの-vオプション
6.1.3 ケーススタディ:GCC
6.1.4 ケーススタディ:kmail
6.1.5 ケーススタディ:SNG
6.1.6 terminfoデータベース
6.1.7 Freecivデータファイル
6.2 透明性と開示性が得られる設計
6.2.1 透明性の禅
6.2.2 透明性と開示性を実現するコーディング
6.2.3 透明性と過剰防衛の回避
6.2.4 透明性と編集可能な表現
6.2.5 透明性、誤りの診断と修復
6.3 メンテナンス性を実現する設計
第7章 マルチプログラミング:プロセスを機能別に分割する
7.1 複雑さの支配とパフォーマンスのチューニングの分割
7.2 UnixIPCメソッドの分類学
7.2.1 専用プログラムに処理を委ねる
7.2.2 パイプ、リダイレクト、フィルタ
7.2.3 ラッパー
7.2.4 セキュリティラッパーとBernsteinチェーン
7.2.5 スレーブプロセス
7.2.6 ピアツーピアのプロセス間通信(IPC)
7.3 問題点や避けるべき方法
7.3.1 時代遅れになったUnixのIPCメソッド
7.3.2 リモートプロシージャ呼び出し
7.3.3 マルチスレッド――脅威それとも厄介者
7.4 設計レベルでのプロセス分割
第8章 ミニ言語:歌いだす記法を探す
8.1 言語の分類学
8.2 ミニ言語の応用
8.2.1 ケーススタディ:sng
8.2.2 ケーススタディ:正規表現
8.2.3 ケーススタディ:Glade
8.2.4 ケーススタディ:m4
8.2.5 ケーススタディ:XSLT
8.2.6 ケーススタディ:DWB
8.2.7 ケーススタディ:fetchmailの実行制御ファイルの構文
8.2.8 ケーススタディ:awk
8.2.9 ケーススタディ:PostScript
8.2.10 ケーススタディ:bcとdc
8.2.11 ケーススタディ:Emacs Lisp
8.2.12 ケーススタディ:JavaScript
8.3 ミニ言語の設計
8.3.1 適切な複雑度の選択
8.3.2 言語の拡張と組み込みの言語
8.3.3 カスタム文法の作成
8.3.4 マクロには注意
8.3.5 言語かアプリケーションプロトコルか
第9章 コード生成:高い水準で規定する
9.1 データ駆動プログラミング
9.1.1 ケーススタディ:ascii
9.1.2 ケーススタディ:統計的SPAMフィルタ
9.1.3 ケーススタディ:fetchmailconfのメタクラスハック
9.2 その場限りのコード生成
9.2.1 ケーススタディ:asciiの表示のためのコード生成
9.2.2 ケーススタディ:表形式のリストに対応するHTMLコードの生成
第10章 設定:気持ちよくスタートしよう
10.1 何を設定可能にすべきか
10.2 設定のありか
10.3 実行制御ファイル
10.3.1 ケーススタディ:.netrcファイル
10.3.2 他のオペレーティングシステムに対する移植性
10.4 環境変数
10.4.1 システム環境変数
10.4.2 ユーザー環境変数
10.4.3 環境変数をいつ使うべきか
10.4.4 他のオペレーティングシステムへの移植性
10.5 コマンド行オプション
10.5.1 コマンド行オプション-aから-zまで
10.5.2 他のオペレーティングシステムへの移植性
10.6 どの方法を選ぶか
10.6.1 ケーススタディ:fetchmail
10.6.2 ケーススタディ:XFree86サーバ
10.7 これらのルールを破ると
第11章 ユーザーインターフェイス:Unix環境におけるユーザーインターフェイス設計
11.1 驚き最小の原則をあてはめる
11.2 Unixのインターフェイス設計の歴史
11.3 インターフェイス設計の評価方法
11.4 CLIとビジュアルインターフェイスのトレードオフ
11.4.1 ケーススタディ:電卓プログラムを書くための2つの方法
11.5 透明性、表現性、設定可能性
11.6 Unixのインターフェイス設計のパターン
11.6.1 フィルタパターン
11.6.2 キャントリップパターン
11.6.3 ソースパターン
11.6.4 シンクパターン
11.6.5 コンパイラパターン
11.6.6 edパターン
11.6.7 rogue風パターン
11.6.8 「エンジンとインターフェイスの分離」パターン
11.6.9 CLIサーバパターン
11.6.10 言語ベースのインターフェイスパターン
11.7 Unixインターフェイス設計パターンの使い方
11.7.1 ポリバレントプログラムパターン
11.8 普遍的なフロントエンドとしてのWebブラウザ
11.9 沈黙は金なり
第12章 最適化
12.1 何かしなくちゃ、じゃない。じっとしていろ!
12.2 最適化する前に計測せよ
12.3 局所化できていないことの害
12.4 スループットとレイテンシ
12.4.1 バッチ処理
12.4.2 処理のオーバーラップ
12.4.3 処理結果のキャッシュ
第13章 複雑さ:できる限り単純に、それよりも単純でなく
13.1 複雑さとは何か
13.1.1 複雑さを生む3つの源泉
13.1.2 インターフェイスの複雑さと実装の複雑さのトレードオフ
13.1.3 本質的な複雑さ、選択上の複雑さ、付随的な複雑さ
13.1.4 複雑さの見取り図
13.1.5 単純なだけでは十分でない場合
13.2 5 エディタ物語
13.2.1 ed
13.2.2 vi
13.2.3 Sam
13.2.4 Emacs
13.2.5 Wily
13.3 エディタの適正サイズ
13.3.1 複雑さが問題となる場所
13.3.2 妥協はつまずく
13.3.3 EmacsはUnixの伝統に対する反証になるか
13.4 ソフトウェアの適正なサイズ
第3部 実装
第14章 言語:CすべきかCせざるべきか?
14.1 Unixの言語の打出の小槌
14.2 なぜCではないのか
14.3 インタープリタ言語と言語併用戦略
14.4 言語の評価
14.4.1 C
14.4.2 C++
14.4.3 シェル
14.4.4 Perl
14.4.5 Tcl
14.4.6 Python
14.4.7 Java
14.4.8 Emacs Lisp
14.5 未来に向けての流れ
14.6 Xツールキットの選び方
第15章 ツール:開発の戦略
15.1 デベロッパフレンドリなオペレーティングシステム
15.2 エディタの選び方
15.2.1 viについて知っていると便利なこと
15.2.2 Emacsについて知っていると便利なこと
15.2.3 新興宗教の信者的でない選び方:両方を使う
15.3 専用コードジェネレータ
15.3.1 yaccとlex
15.3.2 ケーススタディ:Glade
15.4 make:レシピの自動化
15.4.1 makeの基本理論
15.4.2 C/C++以外の開発でのmake
15.4.3 ユーティリティプロダクション
15.4.4 メイクファイルの生成
15.5 バージョン管理システム
15.5.1 なぜバージョン管理か
15.5.2 手作業によるバージョン管理
15.5.3 自動化されたバージョン管理
15.5.4 バージョン管理のためのUnixツール
15.6 実行時デバッグ
15.7 プロファイリング
15.8 Emacsとツールの組み合わせ
15.8.1 Emacsとmake
15.8.2 Emacsと実行時デバッグ
15.8.3 Emacsとバージョン管理
15.8.4 Emacsとプロファイリング
15.8.5 IDEと同じかそれ以上
第16章 再利用:やり直しを避けること
16.1 J. Randam Newbieの物語
16.2 再利用の鍵としての透明性
16.3 再利用からオープンソースへ
16.4 もっとも優れたものはオープンだ
16.5 どこで探すか
16.6 オープンソースソフトウェアを使ううえでの問題点
16.7 ライセンスの問題
16.7.1 オープンソースと呼ばれるための資格
16.7.2 標準的なオープンソースライセンス
16.7.3 法律家が必要になるとき
第4部 コミュニティ
第17章 移植性:ソフトウェアの移植性と標準の維持
17.1 Cの発達
17.1.1 Cの初期の歴史
17.1.2 C標準
17.2 Unix標準
17.2.1 標準規格とUnix戦争
17.2.2 勝利の宴に現れた亡霊
17.2.3 オープンソースの世界におけるUnix標準
17.3 IETFとRFCの標準化プロセス
17.4 DNAとしての仕様とRNAとしてのコード
17.5 移植性を確保するプログラミング
17.5.1 言語の選択と移植性
17.5.2 システムへの依存を避けるには
17.5.3 移植性を確保するためのツール
17.6 国際化
17.7 移植性、オープン標準、オープンソース
第18章 ドキュメント:Web中心の世界でコードの説明をする
18.1 ドキュメントの概念
18.2 Unixスタイル
18.2.1 大規模ドキュメントへの偏り
18.2.2 文化的なスタイル
18.3 Unixドキュメントフォーマット
18.3.1 troffとDWBツール
18.3.2 TEX
18.3.3 Texinfo
18.3.4 POD
18.3.5 HTML
18.3.6 DocBook
18.4 現在の混沌と脱出口
18.5 DocBook
18.5.1 DTD
18.5.2 その他のDTD
18.5.3 DocBookツールチェーン
18.5.4 移植ツール
18.5.5 編集ツール
18.5.6 関連する標準と実践
18.5.7 SGML
18.5.8 XML-DocBookの参考文献
18.6 Unixでドキュメントを書くための最良の方法
第19章 オープンソース:新しいUnixコミュニティでのプログラミング
19.1 Unixとオープンソース
19.2 オープンソースデベロッパたちと共同作業するための最良の方法
19.2.1 パッチの優れた方法
19.2.2 プロジェクトとアーカイブの優れた命名方法
19.2.3 開発の優れた方法
19.2.4 ディストリビューション作成のためのよい方法
19.2.5 コミュニケーションの優れた方法
19.3 ライセンスの論理:どれを選ぶか
19.4 標準ライセンスを使ったほうがよい理由
19.5 さまざまなオープンソースライセンス
19.5.1 MITまたはXコンソーシアムライセンス
19.5.2 BSD Classic License
19.5.3 Artistic License
19.5.4 GPL
19.5.5 MPL
第20章 未来:危険と可能性
20.1 Unixの伝統における本質と偶然
20.2 Plan 9:未来はかつてどうだったか
20.3 Unixの設計の問題点
20.3.1 Unixファイルはバイトを集めた大きな袋に過ぎない
20.3.2 UnixのGUIサポートは弱い
20.3.3 ファイルを削除すると復活できない
20.3.4 Unixは静的なファイルシステムを前提としている
20.3.5 ジョブ制御の設計がお粗末だった
20.3.6 UnixAPIは例外を使わない
20.3.7 ioctl(2)とfcntl(2)がごちゃごちゃしている
20.3.8 Unixのセキュリティモデルが原始的過ぎる
20.3.9 Unixは異なる種類の名前が多すぎる
20.3.10 ファイルシステムはまちがっているかもしれない
20.3.11 グローバルなインターネットアドレス空間に向かって
20.4 Unixの環境の問題点
20.5 Unix文化の問題点
20.6 信じる理由
付録A 略語集
付録B 参考文献
付録C 寄稿者紹介
付録D 無根的根:不宇先生のUnix公案
D.1 エディタのイントロダクション
D.2 不宇先生と1万行
D.3 不宇先生とスクリプト
D.4 不宇先生が2つの道を説く
D.5 不宇先生と方法論者
D.6 不宇先生がグラフィカルユーザーインターフェイスを説く
D.7 不宇先生とUnixの熱心な支持者
D.8 不宇先生がUnix相を説く
D.9 不宇先生とエンドユーザー